import {Ref,ref} from "vue"
import {
  useElementSize,
  useScroll,
  useEventListener,
  watchDebounced
} from "@vueuse/core";
// import { left } from "inquirer/lib/utils/readline";
//
interface Config {
  containerRef:Ref<HTMLElement|undefined>
  contentRef:Ref<HTMLElement|undefined>
  trackXRef:Ref<HTMLElement|undefined>
  trackYRef:Ref<HTMLElement|undefined>
  thumbXRef:Ref<HTMLElement|undefined>
  thumbYRef:Ref<HTMLElement|undefined>
  minThumbSize:number;
  autoHide:boolean;
  trackSize:number | [width:number,height:number]
}

export default class ScrollUtil {
  public containerRef:Ref<HTMLElement|undefined>
  public contentRef:Ref<HTMLElement|undefined>
  public trackXRef:Ref<HTMLElement|undefined>
  public trackYRef:Ref<HTMLElement|undefined>
  public thumbXRef:Ref<HTMLElement|undefined>
  public thumbYRef:Ref<HTMLElement|undefined>
  public thumbXSize = ref(0);
  public thumbYSize = ref(0);
  public trackOpacity = ref(1);
  public trackVisible = ref(false)
  public autoHide = true;
  public trackXSize;
  public trackYSize;
  constructor(config:Config){
    this.containerRef = config.containerRef;
    this.contentRef = config.contentRef;
    this.trackXRef = config.trackXRef;
    this.trackYRef = config.trackYRef;
    this.thumbXRef = config.thumbXRef;
    this.thumbYRef = config.thumbYRef;
    this.thumbXSize.value = config.minThumbSize;
    this.thumbYSize.value = config.minThumbSize;
    this.autoHide = config.autoHide;
    this.trackXSize = Array.isArray(config.trackSize) ? config.trackSize[1] : config.trackSize;
    this.trackYSize = Array.isArray(config.trackSize) ? config.trackSize[0] : config.trackSize;
    this.trackVisible.value = !config.autoHide;
    //
  }
  public contentWidth = 0;
  public contentHeight = 0;
  contentScrollWidth = 0;
  contentScrollHeight = 0;
  speedX = 1;
  speedY = 1;
  public offsetX = ref(0);
  public offsetY = ref(0);
  public scrollX = ref(0);
  public scrollY = ref(0);
  public isScroll = ref(false);
  public isScrollX = ref(false);
  public isScrollY = ref(false);
  public showX = ref(false);
  public showY = ref(false);
  public isHover = ref(false);
  public alignSize = ref([0,0]);
  maxOffsetX = 0;
  maxOffsetY = 0;
  // 计算属性 是否显示 track SU.isHover.value || SU.isScroll.value || !autoHide
  
  // 事件
  dragEventHandle:any = undefined;
  moveEventHandle:any = undefined;
  //
  init(){
    this.setContentSize();
    // this.showScrollBar();
    this.initContentScroll();
    // this.calcThumbSize();
    this.calcAlignSize();
    this.listenContentSizeChange();
  }
  // 监听 size 变化
  listenContentSizeChange(){
    const cs = useElementSize(this.contentRef.value)
    watchDebounced(() => [cs.width.value,cs.height.value],() => {
      this.setContentSize();
      this.calcAlignSize();
    },{debounce:100})
  }
  
  // 初始化 content size
  setContentSize(){
    if(this.contentRef.value){
      this.contentWidth = this.contentRef.value.offsetWidth;
      this.contentHeight = this.contentRef.value.offsetHeight;
      this.contentScrollWidth = this.contentRef.value.scrollWidth;
      this.contentScrollHeight = this.contentRef.value.scrollHeight;
      this.showX.value = this.contentScrollWidth > this.contentWidth;
      this.showY.value = this.contentScrollHeight > this.contentHeight;
    }
    console.log(this.contentWidth,this.contentHeight,this.contentScrollWidth,this.contentScrollHeight)
  }
  //
  initContentScroll(){
    // this.isHover = useElementHover(this.containerRef,{delayLeave:1000});
    const {x,y} = useScroll(this.contentRef);
    this.scrollX = x;
    this.scrollY = y;
  }
  // 是否需要显示滚动条
  showScrollBar(){
    this.showX.value = this.contentScrollWidth > this.contentWidth;
    this.showY.value = this.contentScrollHeight > this.contentHeight;
  }

  // 计算两个导轨互相叠加的部分
  calcAlignSize(){
    const bool = this.showX.value && this.showY.value;
    let r = [0,0];
    if(bool){
      r = [this.trackYSize,this.trackXSize];
    }
    // if(this.alignSize.value[0] == r[0] && this.alignSize.value[1] == r[1]){
    //   return ;
    // }
    this.alignSize.value = r;
    this.calcThumbSize();
  }
  // 滑块大小计算
  calcThumbSize(){
    const tw = this.contentScrollWidth - this.contentWidth; // 内容超出的长度
    const th = this.contentScrollHeight - this.contentHeight;// 内容超出的长度
    const mtx = this.contentWidth - this.thumbXSize.value - this.alignSize.value[0]; // 最大剩余轨道长度 
    const mty = this.contentHeight - this.thumbYSize.value - this.alignSize.value[1]; // 最大剩余轨道长度
    console.log(tw,th,mtx,mty,this.contentWidth,this.contentHeight,this.thumbYSize.value,this.alignSize)
    if(mtx >= tw){
      this.thumbXSize.value = this.contentWidth - tw;
    }
    else{
      // 
      this.speedX = tw / mtx;
    }
    // 
    if(mty >= th){
      this.thumbYSize.value = this.contentHeight - th;
    }
    else{
      this.speedY = th / mty;
    }
    // 
    this.maxOffsetX = this.contentWidth - this.thumbXSize.value - this.alignSize.value[0];
    this.maxOffsetY = this.contentHeight - this.thumbYSize.value- this.alignSize.value[1];
  }

  // 滑块位置计算
  calcThumbXPos(offset:number){
    let r = this.offsetX.value + offset;
    if(r < 0){
      r = 0
    }
    else if(r > this.maxOffsetX){
      r = this.maxOffsetX;
    }
    this.offsetX.value = r;
    return true;
  }

  calcThumbYPos(offset:number){
    let r = this.offsetY.value + offset;
    if(r < 0){
      r = 0
    }
    else if(r > this.maxOffsetY){
      r = this.maxOffsetY;
    }
    this.offsetY.value = r;
    return true;
  }
  // 重新计算内容页的滚动位置
  calcScrollXPos(){
    this.scrollX.value = Math.round(this.offsetX.value * this.speedX);
    return true;
  }
  calcScrollYPos(){
    this.scrollY.value = Math.round(this.offsetY.value * this.speedY);
    return true;
  }
  // 取消move 事件
  unregistMoveEvet(){
    if(this.moveEventHandle){
      this.moveEventHandle();
      this.moveEventHandle = undefined;
    }
  }
  // 滑块拖拽事件
  thumbDragHandle(evt:MouseEvent,type:"X"|"Y"){
    evt.stopPropagation();
    evt.preventDefault();
    this.unregistMoveEvet();
    let {x:sx,y:sy} = evt
    this.moveEventHandle = useEventListener(document,"mousemove",(evt:MouseEvent) => {
      const dx = evt.x - sx;
      const dy = evt.y - sy;
      //
      type == "X" ? (this.calcThumbXPos(dx) && this.calcScrollXPos()) : (this.calcThumbYPos(dy) && this.calcScrollYPos());
      //
      sx = evt.x;
      sy = evt.y;
    })
    //
    this.isScroll.value = true;
    type == "X" ? this.isScrollX.value = true : this.isScrollY.value = true;
    this.showTrack();
  }
  // 轨道点击事件
  trackClickHandle(evt:MouseEvent,type:"X"|"Y"){
    evt.stopPropagation();
    evt.preventDefault();
    console.log('====>',evt,type)
  }
  // 由滚动事件触发的位置变化重新计算滑块的位置
  scrollEventHandle(evt:Event){
    evt.stopPropagation();
    evt.preventDefault();
    
    // console.log('..............',this.scrollY.value,this.offsetY.value)
    if(this.scrollX.value > 0){
      this.offsetX.value = Math.round(this.scrollX.value / this.speedX);
    }
    if(this.scrollY.value > 0){
      this.offsetY.value = Math.round(this.scrollY.value / this.speedY);
    }
  }
  mouseEnterHandle(){
    this.isHover.value = true;
    this.showTrack()
  }
  mouseLeaveHandle(){
    this.isHover.value = false;
    this.hideTrack();
  }
  mouseUpHandle(){
    this.unregistMoveEvet()
    this.isScrollX.value = false;
    this.isScrollY.value = false;
    this.isScroll.value = false;
    //
    this.hideTrack();
  }
  //
  showTrack(){
    if(this.autoHide === false) return;
    this.trackOpacity.value = 1;
    this.trackVisible.value = true;
  }
  hideTrack(){
    if(this.autoHide === false) return;
    if(!(this.isHover.value || this.isScroll.value)){
      this.trackOpacity.value = 0;
      setTimeout(() => {
        this.trackVisible.value = this.isScroll.value || this.isHover.value;
      },1000)
    }
  }
  // 常驻事件注册
  registEvent(){
    // 鼠标进入事件
    useEventListener(this.containerRef,"mouseenter",() => this.mouseEnterHandle())
    useEventListener(this.containerRef,"mouseleave",() => this.mouseLeaveHandle())
    // 滑块拖拽事件
    useEventListener(this.thumbXRef,"mousedown",(evt:MouseEvent) => this.thumbDragHandle(evt,'X'))
    useEventListener(this.thumbYRef,"mousedown",(evt:MouseEvent) => this.thumbDragHandle(evt,'Y'))
    // 轨道点击事件
    useEventListener(this.trackXRef,"click",(evt:MouseEvent) => this.trackClickHandle(evt,"X"))
    useEventListener(this.trackYRef,"click",(evt:MouseEvent) => this.trackClickHandle(evt,"Y"))
    // 滚轮事件
    useEventListener(this.contentRef,"scroll",(evt) => this.scrollEventHandle(evt))
    // pageDown
    // pageUp
    // mouseup
    useEventListener(document,"mouseup",() => this.mouseUpHandle())
    // resize
    useEventListener(this.contentRef,"resize",() => {
      this.setContentSize();
      this.calcAlignSize();
      // this.showScrollBar();
    })
  }
  

}